package com.lznb.cloud.service.impl;

import com.lznb.cloud.entity.NewsAdvertisement;
import com.lznb.cloud.entity.Tcommaccount;
import com.lznb.cloud.repository.NewsAdvertisementRepository;
import com.lznb.cloud.service.NewsAdvertisementService;
import com.lznb.cloud.utils.JsonResultExt;
import com.lznb.cloud.utils.SQLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.lznb.cloud.entity.News;
import com.lznb.cloud.entity.NewsCategory;
import com.lznb.cloud.repository.NewsCategoryRepository;
import com.lznb.cloud.service.NewsCategoryService;
import com.lznb.cloud.service.NewsService;
import com.lznb.cloud.utils.JsonResultExt;
import com.lznb.cloud.utils.SQLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@Service
@CacheConfig(cacheNames = "newsAdvertisement")
public class NewsAdvertisementServiceImpl implements NewsAdvertisementService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private NewsAdvertisementRepository newsAdvertisementRepository;


    @Override
    @CachePut(key = "#root.caches[0].name + ':' + #p0")
    public NewsAdvertisement getNewsAdvertisement(String advertisementId) {
        return newsAdvertisementRepository.findOne(advertisementId);
    }

    @Override
    public JsonResultExt save(NewsAdvertisement newsAdvertisement) {
        JsonResultExt jsonResultExt = new JsonResultExt();
        jsonResultExt.run(jsonResultExt, newsAdvertisementRepository.save(newsAdvertisement));
        return jsonResultExt;
    }

    @Override
    @CachePut(key = "#root.caches[0].name + ':' + #p0.advertisementId")
    public JsonResultExt update(NewsAdvertisement newsAdvertisement) {
        JsonResultExt jsonResultExt = new JsonResultExt();
        jsonResultExt.run(jsonResultExt, newsAdvertisementRepository.saveAndFlush(newsAdvertisement));
        return jsonResultExt;
    }

    @Override
    @CacheEvict(key = "#root.caches[0].name + ':' + #p0")
    public JsonResultExt delete(String advertisementId) {
        JsonResultExt jsonResultExt = new JsonResultExt();
        newsAdvertisementRepository.delete(advertisementId);
        return jsonResultExt;
    }

    @Override
    public Map findByPage(Integer pageIndex, Integer size, NewsAdvertisement newsAdvertisement, Map<String, String> condition) {
        Sort sort = new Sort(Sort.Direction.DESC, "advertisementId");
        Pageable pageable = new PageRequest(pageIndex, size, sort);
        Specification<NewsAdvertisement> specification = this.handleSpeci(newsAdvertisement, condition);
        Page<NewsAdvertisement> list = newsAdvertisementRepository.findAll(specification, pageable);
        Map map = new HashMap();
        map.put("code", 0);
        map.put("msg", "");
        map.put("count", list.getTotalElements());
        map.put("data", list.getContent());
        return map;
    }


    /***
     * 考查询条件处理<br>
     *
     * @param newsAdvertisement {@link NewsAdvertisement} 查询条件实体
     * @return {@link Specification}
     */
    public Specification<NewsAdvertisement> handleSpeci(NewsAdvertisement newsAdvertisement, Map<String, String> condition) {
        Specification<NewsAdvertisement> specification = new Specification<NewsAdvertisement>() {
            @Override
            public Predicate toPredicate(Root<NewsAdvertisement> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = SQLUtils.CriteriaSQLExt(root, newsAdvertisement, criteriaBuilder, condition);
                // predicates.add(criteriaBuilder.like(root.get(name), "%" + value + "%"));

                if(!StringUtils.isEmpty(newsAdvertisement.getTcommaccount())){
                    if(!StringUtils.isEmpty(newsAdvertisement.getTcommaccount().getAccCname())){
                        Join<NewsAdvertisement,Tcommaccount> join = root.join("tcommaccount", JoinType.INNER);
                        predicates.add(criteriaBuilder.like(join.get("accCname"), "%" + newsAdvertisement.getTcommaccount().getAccCname() + "%"));
                    }
                }

                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return specification;
    }
}
